package service

import (
	"context"
	"encoding/json"
	"fmt"
	"time"

	"Data-API-MCP/backend/internal/domain/entity"
	"Data-API-MCP/backend/internal/domain/repository"

	"github.com/google/uuid"
)

// MCPProtocolService MCP协议服务
type MCPProtocolService struct {
	messageRepo repository.MCPMessageRepository
	contextRepo repository.MCPContextRepository
	modelRepo   repository.MCPModelRepository
}

// NewMCPProtocolService 创建MCP协议服务实例
func NewMCPProtocolService(
	messageRepo repository.MCPMessageRepository,
	contextRepo repository.MCPContextRepository,
	modelRepo repository.MCPModelRepository,
) *MCPProtocolService {
	return &MCPProtocolService{
		messageRepo: messageRepo,
		contextRepo: contextRepo,
		modelRepo:   modelRepo,
	}
}

// HandleMessage 处理MCP消息
func (s *MCPProtocolService) HandleMessage(ctx context.Context, message *entity.MCPMessage) error {
	// 1. 验证消息
	if err := s.validateMessage(message); err != nil {
		return fmt.Errorf("消息验证失败: %w", err)
	}

	// 2. 获取或创建上下文
	mcpContext, err := s.getOrCreateContext(ctx, message)
	if err != nil {
		return fmt.Errorf("获取上下文失败: %w", err)
	}

	// 3. 更新消息状态为处理中
	if err := s.messageRepo.UpdateMessageStatus(ctx, message.ID, entity.MessageStatusProgress); err != nil {
		return fmt.Errorf("更新消息状态失败: %w", err)
	}

	// 4. 处理消息
	if err := s.processMessage(ctx, message, mcpContext); err != nil {
		// 更新消息状态为失败
		_ = s.messageRepo.UpdateMessageStatus(ctx, message.ID, entity.MessageStatusFailed)
		return fmt.Errorf("处理消息失败: %w", err)
	}

	// 5. 更新上下文
	mcpContext.LastMessageID = message.ID
	if err := s.contextRepo.UpdateContext(ctx, mcpContext); err != nil {
		return fmt.Errorf("更新上下文失败: %w", err)
	}

	// 6. 更新消息状态为成功
	now := time.Now()
	message.ProcessedAt = &now
	return s.messageRepo.UpdateMessageStatus(ctx, message.ID, entity.MessageStatusSuccess)
}

// CreateContext 创建MCP上下文
func (s *MCPProtocolService) CreateContext(ctx context.Context, mcpContext *entity.MCPContext) error {
	// 生成上下文ID
	if mcpContext.ID == "" {
		mcpContext.ID = uuid.New().String()
	}

	// 设置初始状态
	if mcpContext.Status == "" {
		mcpContext.Status = entity.ContextStatusActive
	}

	return s.contextRepo.CreateContext(ctx, mcpContext)
}

// GetContext 获取MCP上下文
func (s *MCPProtocolService) GetContext(ctx context.Context, id string) (*entity.MCPContext, error) {
	return s.contextRepo.GetContext(ctx, id)
}

// UpdateContextState 更新上下文状态
func (s *MCPProtocolService) UpdateContextState(ctx context.Context, id string, state interface{}) error {
	return s.contextRepo.UpdateContextState(ctx, id, state)
}

// RegisterModel 注册MCP模型
func (s *MCPProtocolService) RegisterModel(ctx context.Context, model *entity.MCPModel) error {
	// 检查模型是否已存在
	existingModel, err := s.modelRepo.GetModelByVersion(ctx, model.Name, model.Version)
	if err == nil && existingModel != nil {
		return fmt.Errorf("模型版本已存在: %s-%s", model.Name, model.Version)
	}

	// 生成模型ID
	if model.ID == "" {
		model.ID = uuid.New().String()
	}

	// 设置初始状态
	if model.Status == "" {
		model.Status = entity.ModelStatusActive
	}

	return s.modelRepo.CreateModel(ctx, model)
}

// GetModel 获取MCP模型
func (s *MCPProtocolService) GetModel(ctx context.Context, id string) (*entity.MCPModel, error) {
	return s.modelRepo.GetModel(ctx, id)
}

// validateMessage 验证消息
func (s *MCPProtocolService) validateMessage(message *entity.MCPMessage) error {
	if message.Type == "" {
		return fmt.Errorf("消息类型不能为空")
	}
	if message.Version == "" {
		return fmt.Errorf("协议版本不能为空")
	}
	if message.ModelID == "" {
		return fmt.Errorf("模型ID不能为空")
	}
	return nil
}

// getOrCreateContext 获取或创建上下文
func (s *MCPProtocolService) getOrCreateContext(ctx context.Context, message *entity.MCPMessage) (*entity.MCPContext, error) {
	if message.ContextID != "" {
		// 尝试获取现有上下文
		mcpContext, err := s.contextRepo.GetContext(ctx, message.ContextID)
		if err == nil {
			return mcpContext, nil
		}
	}

	// 创建新上下文
	mcpContext := &entity.MCPContext{
		ID:        uuid.New().String(),
		ServiceID: message.ModelID, // 使用模型ID作为服务ID
		Status:    entity.ContextStatusActive,
	}

	if err := s.contextRepo.CreateContext(ctx, mcpContext); err != nil {
		return nil, err
	}

	return mcpContext, nil
}

// processMessage 处理消息
func (s *MCPProtocolService) processMessage(ctx context.Context, message *entity.MCPMessage, mcpContext *entity.MCPContext) error {
	// 获取模型
	model, err := s.modelRepo.GetModel(ctx, message.ModelID)
	if err != nil {
		return fmt.Errorf("获取模型失败: %w", err)
	}

	// 解析消息负载
	var payload map[string]interface{}
	if err := json.Unmarshal(message.Payload, &payload); err != nil {
		return fmt.Errorf("解析消息负载失败: %w", err)
	}

	// 根据模型类型处理消息
	switch model.Type {
	case "sql":
		return s.processSQLMessage(ctx, message, mcpContext, model, payload)
	case "function":
		return s.processFunctionMessage(ctx, message, mcpContext, model, payload)
	default:
		return fmt.Errorf("不支持的模型类型: %s", model.Type)
	}
}

// processSQLMessage 处理SQL类型的消息
func (s *MCPProtocolService) processSQLMessage(
	ctx context.Context,
	message *entity.MCPMessage,
	mcpContext *entity.MCPContext,
	model *entity.MCPModel,
	payload map[string]interface{},
) error {
	// TODO: 实现SQL消息处理逻辑
	return nil
}

// processFunctionMessage 处理Function类型的消息
func (s *MCPProtocolService) processFunctionMessage(
	ctx context.Context,
	message *entity.MCPMessage,
	mcpContext *entity.MCPContext,
	model *entity.MCPModel,
	payload map[string]interface{},
) error {
	// TODO: 实现Function消息处理逻辑
	return nil
}
